package com.ihr360.validation;

import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.context.SpringContext;
import com.ihr360.validation.annonation.Valid;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Aspect
@Component
public class ValidationAspect {
//    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
//    private void controllerInvocation() {
//    }

    @Pointcut("@annotation(com.ihr360.validation.annonation.EnableValidation)")
    private void validationInvocation() {
    }

    @Before("validationInvocation()")
    public void validateBefore(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature mSignature = (MethodSignature) signature;
        Object[] args = joinPoint.getArgs();
        if (CollectionUtils.isEmpty(args)) {
            return;
        }
        Class<?> declaringType = mSignature.getDeclaringType();
        Method method = declaringType.getDeclaredMethod(mSignature.getName(), mSignature.getParameterTypes());
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        if (parameterAnnotations == null) {
            return;
        }
        int length = parameterAnnotations.length;
        for (int index = 0; index < length; index++) {
            for (Annotation ann : method.getParameterAnnotations()[index]) {
                if (Valid.class.isInstance(ann)) {
                    Valid valid = (Valid) ann;
                    Class clazz = valid.validator();
                    if (valid.validator().equals(Validator.class)) {
                        return;
                    } else {
                        if (Validator.class.isAssignableFrom(clazz)) {
                            Validator validator = (Validator) SpringContext.getBean(clazz);
                            if (validator==null){
                                validator = (Validator)BeanUtils.instantiate(clazz);
                            }
                            ValidationUtils.invokeValidator(validator, args[index]);
                        }
                    }
                }
            }
        }
    }
}